package com.lianyu507.aop;

import com.lianyu507.annotation.DataOperation;
import com.lianyu507.pojo.MbManager;
import com.lianyu507.pojo.MbUser;
import com.lianyu507.task.LogTask;
import com.lianyu507.util.UserContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * =================================
 * <p>
 * Created by Administrator on 2017/11/22.
 * <p>
 * 描述:
 */
@Aspect
@Component
public class OperationLog {

    private static final Logger log = LoggerFactory.getLogger(OperationLog.class);

    @Pointcut(value = "@annotation(com.lianyu507.annotation.DataOperation)")
    public void cutService() {
    }

    @Around("cutService()")
    public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
        //先执行业务
        Object result = point.proceed();
        try {
            handle(point);
        } catch (Exception e) {
            log.error("日志记录出错!", e);
        }
        return result;
    }

    public void handle(ProceedingJoinPoint point) throws NoSuchMethodException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //读取session中的用户
        MbUser user = UserContext.getCurrentUser();
        MbManager manager = UserContext.getCurrentManager();
        Map<String, Object> map = new HashMap<>();
        if(user==null && manager==null){
            return ; //如果session中没有user,证明没有用户登录,不做日志
        }else if(user!=null){
            map.put("userId",  user.getId());
            map.put("isAdmin", (byte) 0);
            map.put("userName", user.getUserName());
        }else{
            //'1 管理员; 2 非管理员',
            byte isAdmin = 1;
            map.put("userId", manager.getId());
            map.put("isAdmin", isAdmin);
            map.put("userName", manager.getManagerName());
        }

            // 读取登陆者ip
            String ip = request.getRemoteAddr();
            map.put("ip", ip);
            map.put("time", new Date());
            // 获取方法名
            Signature signature = point.getSignature();
            MethodSignature methodSignature = null;
            if (!(signature instanceof MethodSignature)) {
                throw new IllegalArgumentException("该注解只能用于方法");
            }
            methodSignature = (MethodSignature) signature;
            Object target = point.getTarget();
            Method currentMethod = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
            String methodName = currentMethod.getName();
            if (methodName.indexOf("login") != -1) {
                map.put("operationLog", "登录");
            }
            if (methodName.indexOf("logout") != -1) {
                map.put("operationLog", "登出");
            }
            if (methodName.indexOf("add") != -1) {
                map.put("operationLog", "增加");
            }
            if (methodName.indexOf("del") != -1) {
                map.put("operationLog", "删除");
            }
            if (methodName.indexOf("update") != -1) {
                map.put("operationLog", "更新");
            }
            if (methodName.indexOf(" find") != -1) {
                map.put("operationLog", "查询");
            }
            DataOperation annotation = currentMethod.getAnnotation(DataOperation.class);
            Integer referenceId = annotation.tableId();
            byte referenceType = annotation.table();
            map.put("referenceId", referenceId);
            // '0 文章 1 生词 ',
            map.put("referenceType", referenceType);
            LogTask.operationLog(map);
        }
    }
